#include "config/config_manager.h"

#include <iostream>
#include <fstream>
#include <sys/stat.h>
#include <unistd.h>
#include <string>

#include <google/protobuf/text_format.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <glog/logging.h>

namespace sysinfo {
namespace monitor {

bool ConfigManager::LoadConfig(const std::string& file_path, ConfigProto* config) {
    std::ifstream config_stream(file_path);
    if (!config_stream.is_open()) {
        LOG(ERROR) << "Failed to open config file: " << file_path;
        return false;
    }

    google::protobuf::io::IstreamInputStream input_stream(&config_stream);
    if (!google::protobuf::TextFormat::Parse(&input_stream, config)) {
        LOG(ERROR) << "Failed to parse config file: " << file_path;
        return false;
    }

    return ValidateConfig(*config);
}

// 检查文件是否存在且可执行
bool IsExecutable(const std::string& path) {
    struct stat st;
    if (stat(path.c_str(), &st) != 0) {
        return false;
    }

    // 检查是否为普通文件且具有可执行权限
    return S_ISREG(st.st_mode) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH));
}

bool ConfigManager::ValidateConfig(const ConfigProto& config) const {
    // 检查必要字段
    if (!config.has_monitor_version()) {
        LOG(ERROR) << "Missing monitor version in config";
        return false;
    }

    // 检查system_tool_executor配置
    for (const auto& tool_config : config.system_tool_executor()) {
        if (tool_config.name().empty()) {
            LOG(ERROR) << "Missing tool name in system_tool_executor config";
            return false;
        }
        if (tool_config.path().empty()) {
            LOG(ERROR) << "Missing tool path in system_tool_executor config";
            return false;
        }

        // 构造完整路径并检查命令是否存在且可执行
        std::string full_path = tool_config.path();
        if (!full_path.empty() && full_path.back() != '/') {
            full_path += "/";
        }
        full_path += tool_config.name();

        if (!IsExecutable(full_path)) {
            LOG(ERROR) << "Tool command not found or not executable: " << full_path;
            return false;
        }
    }

    // 检查system_file_executor配置
    for (const auto& file_config : config.system_file_executor()) {
        if (file_config.name().empty()) {
            LOG(ERROR) << "Missing file name in system_file_executor config";
            return false;
        }
        if (file_config.path().empty()) {
            LOG(ERROR) << "Missing file path in system_file_executor config";
            return false;
        }

        // 构造完整路径并检查文件是否存在
        std::string full_path = file_config.path();
        if (!full_path.empty() && full_path.back() != '/') {
            full_path += "/";
        }
        full_path += file_config.name();

        if (access(full_path.c_str(), R_OK) != 0) {
            LOG(ERROR) << "System file not found or not readable: " << full_path;
            return false;
        }
    }

    return true;
}

}  // namespace monitor
}  // namespace sysinfo